昨天我們讓 Jar 檔在 Linux 伺服器上成功的運行,並介紹了 Container 的基本知識,再來,我們一起看看 Docker 的基本觀念,並利用 Docker 將 Jar 打包成可執行的容器。
昨天提到,Docker 是一種容器化的實踐技術,是一個用來創建並管理容器的工具。他的底層由一個 long time service 的 Docker Daemon 運行,用於管理 Image (映像檔) 與 Container 的運行;而使用者能夠透過 common line 送出 docker 指令,並以 Restful API 和 Docker Daemon 溝通。
而關於 Docker 的運行,我們還需要知道而外三個專有名詞:
Image 是一個唯獨的檔案,其內部包含了開發的程式碼、函式庫以及環境的配置檔案,是容器建立的範本,可以藉由撰寫 Dockerfile 創立(或部分的套件),或是從公開的地方下載。
Container 是由 Image 建立出來的實例 (Process),能夠被使用與管理,同時 Container 之間是相互隔離的,且一個 Image 可以建立出多個 container。
如同程式碼的儲存空間一樣,Image 也有其放置的倉庫位置,如同 GitHub、GitLab 一樣,Image 的倉庫有 Docker Hub,甚至是在私有環境下建立的 On-Premise Registry,如 Harbor。在 Registry 內,也能將 Image 的設定為公開與非公開,或是授權下載使用等。
關於 Docker 的安裝在網路上有諸多的教學,讀者可依照自身的作業系統安裝,這裡就先展示幾個在操作 Docker 上最常用到的指令:
#顯示 Docker 版本,若 docker daemon 是未運行的情況下會跳出提示
docker version
#顯示目前電腦上有的 Docker 映像檔
docker images
#顯示目前電腦上有的 Container
docker ps -a
#從網路上拉取鏡像,預設是從 docker hub 上拉取,後續可以加入私有倉庫的地址
docker pull
#登入 Registry,當 Image 為私人的時候使用
docker login
#利用 DockerFile 創建 Image
docker build
#使用 image 創建 Container
docker run
#停止 Container 的運行
docker stop
#刪除 Container,需要先將其停止
docker rm
#刪除 image
docker rmi
以上就是 docker 操作時的常見指令,後續也會有用到。下一步,我們創建 Dockerfile,並將 Jar 打包成 Dokcer image。
首先,我們開啟 Eclipse 的 color-code-tag 專案,並直接點選專案右鍵 => New => File,並將檔案命名為 Dockerfile,此時它應該會在專案的跟目錄下產生 (與 pom 同位置)。接著我們輸入:
FROM adoptopenjdk/openjdk11:latest
COPY ./target/*.jar cct.jar
RUN sh -c 'touch cct.jar'
ENTRYPOINT ["java","-jar","cct.jar"]
這裡簡單說明一下:FROM adoptopenjdk/openjdk11:latest
: 表示使用了 openjdk11 的 base imageCOPY ./target/*.jar cct.jar
: 將 target 目錄下的 Jar 檔複製到 container 內,並將其命名為 cct.jarRUN sh -c 'touch cct.jar'
: 將 Jar 得時戳記改為現在,不然之後會看到產生的 image 是 1970 那個年代ENTRYPOINT ["java","-jar","cct.jar"]
: 在 container 執行 Jar 檔
這麼一看,好像看出了端倪,概念上是不是很像你準備了一台有安裝 openJDK11 的 VM,並且將 Jar 檔複製進去,並且在啟動它的同時時輸入了啟動 Jar 的指令?
建立好後,先確保專案 target 目錄下有 Jar 檔 (若沒有可參考昨天建構 Jar 檔的流程創建),並右鍵點及專案 Show in local Terminal => Terminal 開啟 cmd,並輸入:
docker build -t cct-java .
則會開始將 Jar 打包成 Docker Image,當完成後,我們在 cmd 內輸入 docker images 後,即可看見 image 已經在我們的電腦中。
接著我們將 image 在本機上執行:
# -p 會將 container 的 port 指向本機的 port,-d 則會讓 container 在背景運行
docker run -p 8081:8081 -d cct-java
接著便可以使用 Postman 對 localhost:8081/getColorTags 發送照片,即可獲得色碼。
而 Angular 一樣在專案資料夾中建立 Dockerfile,並輸入:
FROM node:16.13.0-alpine as builder
COPY . /app
WORKDIR /app
RUN npm install
RUN npm run build --production
FROM nginxinc/nginx-unprivileged
EXPOSE 8080
COPY --from=builder /app/dist/cct-web /usr/share/nginx/html
並在 Dockerfile 的路徑下開啟 cmd 執行:
#將前端編譯與打包
ng build
#建構 Docker
docker build -t cct-web .
接著我們將也將前端的 image 在本機上執行:
docker run -p 4200:8080 -d cct-web
此時,我們便能從 localhost:4200 訪問,並且對已啟動的後端 container 相互發送請求。
今天,我們完成了將 Jar 打包成 Docker Image,並在本機上執行起來,明天,我們先稍微修改一下前端的 API URL,再一起將 Image 推送到 Repository 內,並再伺服器內啟動 container,開放給其他人訪問。
到那時,我們便走完了 Dev + Ops (對,還沒有真的 DevOps !),便可一起來審視這一整段的過程,並帶出我們的金剛戰士 Jenkins。